package com.sx.mvvmlibs.http.tools.encrypts;

import com.google.gson.Gson;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

/**
 * @Author: YY
 * @Date: 2021/4/8
 * @Description: 加解密请求工厂转换器
 */
public class EDRequestConverterFactory extends Converter.Factory {

    private final Gson gson;
    private final GsonConverterFactory gsonConverterFactory;

    private final String clientPriKey;
    private final String serverPubKey;

    public EDRequestConverterFactory(Gson gson, String clientPriKey, String serverPubKey) {
        this.gson = gson;
        this.gsonConverterFactory = GsonConverterFactory.create(gson);

        this.clientPriKey = clientPriKey;
        this.serverPubKey = serverPubKey;
    }

    public static EDRequestConverterFactory create(Gson gson, String priKey, String pubKey) {
        return new EDRequestConverterFactory(gson, priKey, pubKey);
    }

    /**
     * 检查注解数组里是否包含 @EncryptRequest 注解
     * @param annotations 注解数组
     * @return 包含返回true 否则false
     */
    private static boolean containsEncryptAnnotation(Annotation[] annotations) {
        for (Annotation methodAnnotation : annotations) {
            if (methodAnnotation.annotationType() == EncryptRequest.class) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (containsEncryptAnnotation(annotations)) {
            return new EncryptResponseConverter<>(gson, type, serverPubKey);
        } else {
            return gsonConverterFactory.responseBodyConverter(type, annotations, retrofit);
        }
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if (containsEncryptAnnotation(methodAnnotations)) {
            return new EncryptRequestConverter<>(gson, clientPriKey);
        } else {
            return gsonConverterFactory.requestBodyConverter(type, parameterAnnotations, methodAnnotations, retrofit);
        }
    }
}
